package com.swx.identityservice.filter;


import com.alibaba.fastjson.JSONObject;
import com.swx.identityservice.models.ScbpPermission;
import com.swx.identityservice.models.Token;
import com.swx.identityservice.service.LoginUser;
import com.swx.identityservice.service.ScbpPermissionService;
import com.swx.identityservice.service.TokenService;
import com.swx.identityservice.utils.JaxrsResponse;
import com.swx.identityservice.utils.ResponseUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * spring security处理器
 *
 * @version 创建时间：2018年3月20日 下午10:13:18 类说明
 */
@Configuration
@Slf4j
public class SecurityHandlerConfig {

    @Autowired
    private TokenService tokenService;

    @Autowired
    private ScbpPermissionService scbpPermissionService;

    /**
     * 登陆成功，生成并返回Token
     *
     * @return
     */
    @Bean
    public AuthenticationSuccessHandler loginSuccessHandler() {
        return new AuthenticationSuccessHandler() {

            @Override
            public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
                                                Authentication authentication) throws IOException, ServletException {
                LoginUser loginUser = (LoginUser) authentication.getPrincipal();
                Token token = tokenService.saveToken(loginUser);
                //存放该用户的权限
                List<String> listPermissions = new ArrayList<>();
                List<String> allPermissions2 = new ArrayList<>();
                JSONObject jo = new JSONObject();
                List<ScbpPermission> permissions = loginUser.getPermissions();
                for (ScbpPermission p : permissions) {
                    listPermissions.add(p.getPermission());
                }
                try {
                    List<ScbpPermission> allPermissions = scbpPermissionService.getAllPermissions();
                    for (ScbpPermission pp : allPermissions) {
                        allPermissions2.add(pp.getPermission());
                    }
                    List<String> same = new ArrayList<>(allPermissions2);
                    same.retainAll(listPermissions);
                    log.info("same==" + same);
                    for (String j : same) {
                        jo.put(j, true);
                    }
                    allPermissions2.removeAll(same);
                    log.info("notsame==" + allPermissions2);
                    for (String notsame : allPermissions2) {
                        jo.put(notsame, false);
                    }
                    for(String jj : same){
                        ScbpPermission permission = scbpPermissionService.selectParentExist(jj);
                        String pid = getPid(permission.getPid());
                        jo.put(pid,true);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                JSONObject jb = new JSONObject();
                jb.put("access_token", token.getToken());
                jb.put("loginTime", token.getLoginTime());
                jb.put("permissions", jo);
                JaxrsResponse result2 = JaxrsResponse.builder().code(200).status("success").data(jb).build();
                ResponseUtil.responseJson(response, HttpStatus.OK.value(), result2);
            }
        };
    }

    /**
     * 登陆失败
     *
     * @return
     */
    @Bean
    public AuthenticationFailureHandler loginFailureHandler() {
        return new AuthenticationFailureHandler() {

            @Override
            public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
                                                AuthenticationException exception) throws IOException, ServletException {
                String msg ;
                if (exception instanceof BadCredentialsException) {
                    msg = "账号或者密码错误";
                } else {
                    msg = exception.getMessage();
                }
                JaxrsResponse result = JaxrsResponse.builder().status("fail").message(msg).build();
                ResponseUtil.responseJson(response, HttpStatus.OK.value(), result);
            }
        };

    }

    /**
     * 未登录，返回401
     *
     * @return
     */
    @Bean
    public AuthenticationEntryPoint authenticationEntryPoint() {
        return new AuthenticationEntryPoint() {

            @Override
            public void commence(HttpServletRequest request, HttpServletResponse response,
                                 AuthenticationException authException) throws IOException, ServletException {

                JaxrsResponse result = JaxrsResponse.builder().code(200).message("请先登录").build();
                ResponseUtil.responseJson(response, HttpStatus.OK.value(), result);
            }
        };
    }

    /**
     * 退出处理
     *
     * @return
     */
    @Bean
    public LogoutSuccessHandler logoutSussHandler() {
        return new LogoutSuccessHandler() {

            @Override
            public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
                                        Authentication authentication) throws IOException, ServletException {
                JaxrsResponse result = JaxrsResponse.builder().code(200).data("退出成功").build();
                String token = TokenFilter.getToken(request);
                tokenService.deleteToken(token);
                ResponseUtil.responseJson(response, HttpStatus.OK.value(), result);
            }
        };

    }
    //递归查询父节点的权限名，如果该用户下属子节点有权限为true，则将其父节点设置为true
    public String getPid(int id) {
        ScbpPermission permission = scbpPermissionService.selectByPrimaryKey(id);
        if(permission == null){
            return "";
        }
        if (permission.getPid() != 0) {
            return getPid(permission.getPid());
        }
        return permission.getPermission();
    }
}
